package com.xrui.hbasecmd.converters;

import org.w3c.dom.Node;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilderFactory;
import java.awt.*;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * This class is a place holder for XML editors.
 */
public class XmlConverter extends StringConverter {

    private static final long serialVersionUID = -2217840069549275853L;

    @Override
    public boolean isValidForNameConversion() {
        return false;
    }

    @Override
    public boolean supportsFormatting() {
        return true;
    }

    @Override
    public String format(String value) {
        try {
            final InputSource src = new InputSource(new StringReader(value));
            final Node document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement();
            final Boolean keepDeclaration = value.startsWith("<?xml");

            final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
            final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
            final LSSerializer writer = impl.createLSSerializer();

            writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
            writer.getDomConfig().setParameter("xml-declaration", keepDeclaration);

            return writer.writeToString(document);
        } catch (Exception e) {
            LOG.error(String.format("Failed to format xml '%s'.", value), e);
            return value;
        }
    }

    @Override
    public Map<Pattern, Color> getColorMappings() {
        Map<Pattern, Color> colorMap = new HashMap<>();
        colorMap.put(Pattern.compile("(<!\\[CDATA\\[)(?=.*)"), new Color(128, 128, 128));
        colorMap.put(Pattern.compile("(?<=.{0,100})(]]>)"), new Color(128, 128, 128));
        colorMap.put(Pattern.compile("(<\\s*/?\\s*[a-zA-Z-_:.]*)(?=\\s*[ >/])"), new Color(63, 127, 127));
        colorMap.put(Pattern.compile("(/?\\s*>)"), new Color(63, 127, 127));
        colorMap.put(Pattern.compile("(?<=\\s)(\\w*)(?==)"), new Color(127, 0, 127));
        colorMap.put(Pattern.compile("(?<=[a-zA-Z-]{0,100}=)(\"[^\"]*\")"), new Color(42, 0, 255));
        colorMap.put(Pattern.compile("(<!--.*-->)"), new Color(63, 95, 191));

        return colorMap;
    }
}
